﻿//Copyright 2014 Thomas Rega

//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at

//http://www.apache.org/licenses/LICENSE-2.0

//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.

using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Controls;
using System.Windows.Threading;

namespace TinyDeduplicator
{
    internal class RecursiveDeduplicator : IDisposable
    {
        Dispatcher dispatcher;
        Label status;

        private IDictionary<DeduplicationFile, ICollection<DeduplicationFile>> filesDict = new Dictionary<DeduplicationFile, ICollection<DeduplicationFile>>();

        internal RecursiveDeduplicator(Dispatcher dispatcher, Label status)
        {
            this.dispatcher = dispatcher;
            this.status = status;
        }

        internal void deduplicate(DirectoryInfo directoryInfo)
        {
            try
            {
                foreach (FileInfo fileInfo in directoryInfo.EnumerateFiles())
                {
                    try
                    {
                        dispatcher.Invoke(new Action(() => status.Content = "Checking file: " + fileInfo.FullName));
                        DeduplicationFile deduplicationFile = new DeduplicationFile(fileInfo);

                        if (filesDict.ContainsKey(deduplicationFile))
                        {
                            filesDict[deduplicationFile].Add(deduplicationFile);
                        }
                        else
                        {
                            ICollection<DeduplicationFile> files = new List<DeduplicationFile>();
                            files.Add(deduplicationFile);

                            filesDict.Add(deduplicationFile, files);
                        }
                    }
                    catch (UnauthorizedAccessException) { }
                }

                foreach (DirectoryInfo directory in directoryInfo.EnumerateDirectories())
                {
                    deduplicate(directory);
                }
            }
            catch (UnauthorizedAccessException) { }
        }

        internal IList<DeduplicationFile> getDuplicates()
        {
            IList<DeduplicationFile> duplicates = new List<DeduplicationFile>();

            foreach (ICollection<DeduplicationFile> files in filesDict.Values)
            {
                if (files.Count > 1)
                {
                    foreach (DeduplicationFile file in files)
                    {
                        duplicates.Add(file);
                    }
                }
            }

            return duplicates;
        }

        //if I don't do this, vshost32.exe will hang onto the files while debugging -.-;; --trega
        public void Dispose()
        {
            filesDict = null;
            GC.Collect();
        }
    }
}
